#include <stdio.h>
//递归递归，是在函数体内反复地调用该函数。
//第一题、接受一个无符号整型数，按照顺序打印它的每一位。
//例如：输入1234，打印1 2 3 4。
//首先基本工作：定义一个无符号整性数，传参。紧接着分析：每次%10剥一个数出来，那我只要剥到最后一个不能再剥了就可以停止了。
//那么问题来了，怎么知道它是最后一个不能再剥了？
//思考：最后一个要剥的数，也就是最前面的数，它一定是在1~9的范围内，因此，只要满足条件x>9就可以进入反复调用的函数内剥数。
//那是怎么样的函数反复调用呢？起码这个函数你最后要给我打印一个x%10的数吧？
//循环体内，原来的值也要发生变化啊。
//int m = 0;
//void Is_printf(unsigned int x)
//{
//    int a = 0;
//    if(x > 9)
//    {
//        //Is_printf(x / 10);
//        x/=10;
//
//    }
//    printf("%d ",x % 10);
//}
//
//int main() {
//    unsigned int n = 0;
//    scanf("%d",&n);
//    Is_printf(n);
//    return 0;
//}


//第二题、递归和非递归实现求第n个斐波那契数。
//例如：输入：5，输出：5.
//     输入：10，输出：55.
//     输入：2，输出：1.
//那么首先废话不多说，你先要明白什么是斐波那契数列：1,1,2,3,5,8,13,21,34,55...即从第3项开始，第n项为前两项之和。
//1.简单的必要工作先准备好。2.构造函数。明白我传一个参数给你，你要返回一个值给我。
//3.我感觉函数内首先还是要先判断，如果直接输入1或者2，则直接return 2即可，输入其他再来判断。
//递归的版本:
//4.它是一个倒推的关系的：第10项=第9项+第8项，而第9项=等8项+第7项，...
//非递归的版本：
//5.可不可以搞一个循环：不断地相加，直到最后.你会发现：可以设置三个变量，将前面的值赋给后面的值，然后使得c前进为想要的值。
//int fib(int x)
//{
//    if(x == 1 || x == 2)
//        return 1;
//    else
//    {
//        return (fib(x-1)+fib(x-2));
//    }
////    int a = 1;
////    int b = 1;
////    int c =0;
////    if(x == 1 || x == 2)
////        return 1;
////    else
////    {
////        while( x >= 3)
////        {
////             c = a + b;
////             a = b;
////             b = c;
////             x--;
////        }
////        return c;
////    }
//}
//int main()
//{
//    int n = 0;
//    scanf("%d",&n);
//    int ret = fib(n);
//    printf("%d\n",ret);
//    return 0;
//}


////第三题、编写一个函数实现n的k次方。
////(先暂时不考虑k是负数）
////废话不多说，首先第一步，基本工作先做好。其次再弄函数。
////先一步步来，2的K次方。
////1.很明显，函数要返回值。2.条件：k次方不断减一再相乘。
////明天：1.考虑k是负数：还是先一步步来，然后再整合。
//double power(int x,int y)//x:truth,y:index      k为负数版本，注意返回的值为小数。
//{
//    if(y == -1)
//        return 1.0/x;
//    else
//    {
//        return ((1.0/x) * power(x,y+1));
//    }
//}
//int main()
//{
//    int truth = 0;//底数
//    int index = 0;//指数
//    scanf("%d %d",&truth,&index);
//    double ret = power(truth,index);
//    printf("%lf\n",ret);
//    return 0;
//}
//int power(int x,int y)//k为非负数版本
//{
//    if(y == 0)
//        return 1;
//    else if(y == 1)
//        return x;
//    else
//    {
//        return (x*(power(x,y-1)));
//    }
//}
//int main()
//{
//    int truth = 0;//底数,底数全体整数型实数都可以算。
//    int index = 0;//指数
//    scanf("%d %d",&truth,&index);
//    int ret = power(truth,index);
//    printf("%d\n",ret);
//    return 0;
//}
//两个版本整和不了在一起，因为返回的值不一样。一个是整数型，一个是浮点型。


////第四题、写一个递归函数DigitSum(n),输入一个非负整数，返回组成它的数字之和。例如：调用DigitSum(1729)，则应该返回1+7+2+9，它的和是19.
////输入：1729，输出：19.
////1.感觉跟第一题很像，那么废话先不多说，先把必要工作准备好。
////2.函数应该返回一个整数值，然后在该函数体内反复调用该函数。应该先剥数，然后每一次有一个值让他们相加。
//int DigitSum(int x)
//{
//    //int m = 0;
//    if(x > 0)
//    {
//        return x % 10 + DigitSum(x/10);
//    }
//}
//int main()
//{
//    int n = 0;
//    scanf("%d",&n);
//    int ret = DigitSum(n);
//    printf("%d\n",ret);
//    return 0;
//}
////不要用全局变量！！！

//第五题、编写一个函数reverse_string(char* string)(递归实现)
//实现：将参数字符串中的字符反向排列，不是逆序打印。
//要求：不能使用C函数库中的字符串操作函数。（strlen）
//eg.char arr[] = "abcdef",逆序之后数组的内容变成 fedcba.
//1.还是那句话：废话不多说，先把准备工作干好。如果你是数组的话，后面的\0那就是随机遇到了，不是按照预算好的来实现的。
//2.跟剥数有点类似，只不过它是要遇到\0才停下来。待转换的字符数如果>=1,那就不用逆序了。
//遇到数组，我不管有没有用，我都习惯性的把数组、左下标、右下标传进去，必要时还可以传数组长度。
void reverse_string(char arr[],int left,int right)
{
    char m = arr[left];//用一个临时变量把它存着，调用前后变量的位置。
    arr[left] = arr[right];
    arr[right] = m;
    if(right - 1 > 2)//打印在屏幕上的完整的字符个数-两个转换过的=剩下的待转换的字符个数：right+1-2=right-1。
    {
        left+=1;
        right-=1;
        reverse_string(arr,left,right);
    }
}
int main()
{
    char arr[] = "abcde";//它这个其实内部还有一个'\0'的。
    int a = 0,sz = sizeof(arr)/sizeof(arr[0]);//'\0’也算字符的，sizeof()也算'\0'的。————7
    int left = 0;
    int right = sz - 2;//由于下标是从0开始的，所以要-2。//5
    //printf("%d %d",sz,right);//可临时验证数据情况！
    for(a = 0;a <= right;a++)
    {
        printf("%c ",arr[a]);
    }
    reverse_string(arr,left,right);
    //printf("%s",ret);//打印数组不是这样打印的。
    printf("\n");
    for(a = 0;a <= right;a++)
    {
        printf("%c ",arr[a]);
    }
    return 0;
}






////第六题、递归和非递归实现strlen。
////非递归的函数，起码你要定义一个变量来记录长度吧。
////非递归版本：
////int My_strlen(char *arr)
////{
////    int count = 0;
////    while(*arr != '\0')
////    {
////        arr++;
////        count++;
////    }
////    return count;
////}
////int main()
////{
////    char arr[] = "abcdef";
////    int ret = My_strlen(arr);
////    printf("%d\n",ret);
////    return 0;
////}
////递归版本：
////同样的，还是需要值的返回
//int My_strlen(char *arr)
//{
//    while(*arr != '\0')
//    {
//        return 1+My_strlen(arr+1);
//    }
//}
//int main()
//{
//    char arr[] = "ab";
//    int ret = My_strlen(arr);
//    printf("%d\n",ret);
//    return 0;
//}


//第七题、递归和非递归分别实现求n的阶乘（不考虑溢出的问题）。
//其实阶乘，无非还是：n!=n*(n-1)!;(n-1)!=(n-1)*(n-2)!；...直到n是1.
//1.首先必要工作先准备好。2.构造函数。
////递归版本：
//int factorial(int x)
//{
//    if(x == 1)
//        return 1;
//    else
//        return (x * factorial(x-1));
//}
//int main()
//{
//    int n = 0;
//    scanf("%d",&n);
//    int a = factorial(n);
//    printf("%d\n",a);
//    return 0;
//}
////非递归版本：其实是依次递减：eg.10!=10*9*8*7*6*5*4*3*2*1;或者依次递增：eg.5！=1*2*3*4*5；看自己选择。
//int factorial(int x)
//{
//    int i = 0;
//    int m = 1;
//    for(i = 1;i <= x;i++)
//    {
//        m*=i;
//    }
//    return m;
//}
//int main()
//{
//    int n = 0;
//    scanf("%d",&n);
//    int a = factorial(n);
//    printf("%d\n",a);
//    return 0;
//}


////第八题、递归方式实现打印一个整数的每一位
////这不是那个剥数嘛
////if语句走完之后，后面的还要执行。
////
//void print(int x)
//{
//    if(x > 9)
//    {
//        print(x / 10);
//    }
//    printf("%d ",x % 10);
//}
//int main()
//{
//    int n = 0;
//    scanf("%d",&n);
//    print(n);
//    return 0;
//}